package com.cc.moxingvoice.ui.window;

import android.content.Context;
import android.databinding.ViewDataBinding;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Environment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.cc.moxingvoice.BR;
import com.cc.moxingvoice.R;
import com.cc.moxingvoice.constant.LocalPath;
import com.cc.moxingvoice.model.WinVoiceItem;
import com.cc.moxingvoice.model.WinVoiceLabelItem;
import com.cc.moxingvoice.model.WinVoicePackageItem;
import com.cc.moxingvoice.utils.FilesUtil;
import com.cc.moxingvoice.utils.RegexUtil;
import com.mob.analysdk.AnalySDK;
import com.superc.cframework.base.ui.CBaseRecyclerViewAdapter;
import com.superc.cframework.utils.ToastUtil;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

/**
 * 创建日期：2018/2/27 on 9:14
 * 描述：
 * 作者：郭士超
 * QQ：1169380200
 */

public class FloatWindowVoiceView extends LinearLayout {

    /**
     * 记录悬浮窗的宽度
     */
    public static int viewWidth;

    /**
     * 记录悬浮窗的高度
     */
    public static int viewHeight;

    /**
     * 记录系统状态栏的高度
     */
    private static int statusBarHeight;

    /**
     * 用于更新悬浮窗的位置
     */
    private WindowManager windowManager;

    /**
     * 悬浮窗的参数
     */
    private WindowManager.LayoutParams mParams;

    /**
     * 记录当前手指位置在屏幕上的横坐标值
     */
    private float xInScreen;

    /**
     * 记录当前手指位置在屏幕上的纵坐标值
     */
    private float yInScreen;

    /**
     * 记录手指按下时在屏幕上的横坐标的值
     */
    private float xDownInScreen;

    /**
     * 记录手指按下时在屏幕上的纵坐标的值
     */
    private float yDownInScreen;

    /**
     * 记录手指按下时在小悬浮窗的View上的横坐标的值
     */
    private float xInView;

    /**
     * 记录手指按下时在小悬浮窗的View上的纵坐标的值
     */
    private float yInView;

    /**
     * 控件
     */
    private TextView tvTitle;
    private ImageButton ibLeft;
    private ImageButton ibRight;
    private EditText edtName;
    private RecyclerView mRvVoicePackage;
    private RecyclerView mRvVoiceLabel;
    private RecyclerView mRvVoice;

    private List<WinVoicePackageItem> mVoicePackageList;
    private FloatWindowVoicePackageAdapter mVoicePackageAdapter;
    private List<WinVoiceLabelItem> mVoiceLabelList;
    private FloatWindowVoiceLabelAdapter mVoiceLabelAdapter;
    private List<WinVoiceItem> mVoiceList;
    private FloatWindowVoiceAdapter mVoiceAdapter;

    private List<WinVoiceItem> mAllVoiceList;
    private int labelPosition = 0;

    private int voicePackageId;
    private boolean isPackage;
    private boolean isSearch;

    private String qqReceiveVoicePath;
    private String qqSendVoicePath;

    private MediaPlayer mp;//mediaPlayer对象
    private boolean play = false;//是否在播放
    private int playTag = -1;

    public FloatWindowVoiceView(Context context) {
        super(context);
        windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        LayoutInflater.from(context).inflate(R.layout.float_window_voice, this);
        View view = findViewById(R.id.float_window);
        viewWidth = view.getLayoutParams().width;
        viewHeight = view.getLayoutParams().height;

        initView();
        initData();
        initListener();
        initList();
        addVoicePackage();
        initMediaPlayer();
    }

    private void initData() {
        Calendar c = Calendar.getInstance(); // 当前时间
        int year = c.get(Calendar.YEAR); // 获取当前年份
        int month = c.get(Calendar.MONTH) + 1;// 获取当前月份
        int day = c.get(Calendar.DAY_OF_MONTH);// 获取当日期

        String yearMonth = "" + year + (month >= 10 ? "" + month : "0" + month);
        qqReceiveVoicePath = "/" + "ptt/"; //  + yearMonth + "/" + day + "/"
        qqSendVoicePath = "/" + "ptt/" + yearMonth + "/" + day + "/";
    }

    private void initList() {
        mAllVoiceList = new ArrayList<>();

        mVoicePackageList = new ArrayList<WinVoicePackageItem>();
        mRvVoicePackage.setLayoutManager(new LinearLayoutManager(getContext()));
        mVoicePackageAdapter = new FloatWindowVoicePackageAdapter(getContext(), mVoicePackageList, R.layout.float_window_item_voice_package, BR.item);
        mRvVoicePackage.setAdapter(mVoicePackageAdapter); // 这里或者在xml里设置adapter
        mVoicePackageAdapter.setOnItemClickListener(new CBaseRecyclerViewAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(ViewDataBinding binding, int position) {
                switch (position) {
                    case 0:
                        addQQVoice();
                        break;
                    case 1:
                        addWXVoice();
                        break;
                    default:
                        addVoice(mVoicePackageList.get(position).getName());
                        break;
                }

                tvTitle.setText(mVoicePackageList.get(position).getName());
                mRvVoicePackage.setVisibility(GONE);
                isPackage = false;
            }
        });

        mVoiceLabelList = new ArrayList<WinVoiceLabelItem>();
        LinearLayoutManager voiceLabelMs = new LinearLayoutManager(getContext());
        voiceLabelMs.setOrientation(LinearLayoutManager.HORIZONTAL);// 设置 recyclerview 布局方式为横向布局
        mRvVoiceLabel.setLayoutManager(voiceLabelMs);
        mVoiceLabelAdapter = new FloatWindowVoiceLabelAdapter(getContext(), mVoiceLabelList, R.layout.float_window_item_voice_label, BR.item);
        mRvVoiceLabel.setAdapter(mVoiceLabelAdapter); // 这里或者在xml里设置adapter
        mVoiceLabelAdapter.setOnItemClickListener(new CBaseRecyclerViewAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(ViewDataBinding binding, int position) {

                if (labelPosition == position) {
                    return;
                }
                labelPosition = position;
                mVoiceList.clear();
                if (position == 0) {
                    mVoiceList.addAll(mAllVoiceList);
                } else {
                    for (WinVoiceItem item : mAllVoiceList) {
                        if (item.getLabel().equals(mVoiceLabelList.get(position).getName())) {
                            mVoiceList.add(item);
                        }
                    }
                }
                mVoiceAdapter.notifyDataSetChanged();
            }
        });

        mVoiceList = new ArrayList<WinVoiceItem>();
        mRvVoice.setLayoutManager(new LinearLayoutManager(getContext()));
        mVoiceAdapter = new FloatWindowVoiceAdapter(getContext(), mVoiceList, R.layout.float_window_item_voice, BR.item);
        mRvVoice.setAdapter(mVoiceAdapter); // 这里或者在xml里设置adapter
        mVoiceAdapter.setOnItemClickListener(new CBaseRecyclerViewAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(ViewDataBinding binding, int position) {
                playVoiceType(position);

                HashMap<String, Object> eventParams = new HashMap<String, Object>();
                eventParams.put("voice-type", "FloatWindow");
                AnalySDK.trackEvent("play-voice", eventParams);
            }
        });
    }

    private void initListener() {
        ibLeft.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isPackage) {
                    return;
                }
                tvTitle.setText("请选择语音包");
                mRvVoicePackage.setVisibility(VISIBLE);
                isPackage = true;
            }
        });
        ibRight.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                MyWindowManager.hideVoiceWindow(getContext());
            }
        });
    }

    private void initView() {
        tvTitle = findViewById(R.id.tv_title);
        ibLeft = findViewById(R.id.ib_left);
        ibRight = findViewById(R.id.ib_right);
        edtName = findViewById(R.id.edt_name);
        mRvVoicePackage = findViewById(R.id.rv_voice_package);
        mRvVoiceLabel = findViewById(R.id.rv_voice_label);
        mRvVoice = findViewById(R.id.rv_voice);

        tvTitle.setText("请选择语音包");
        isPackage = true;
        isSearch = false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 手指按下时记录必要数据,纵坐标的值都需要减去状态栏高度
                xInView = event.getX();
                yInView = event.getY();
                xDownInScreen = event.getRawX();
                yDownInScreen = event.getRawY() - getStatusBarHeight();
                xInScreen = event.getRawX();
                yInScreen = event.getRawY() - getStatusBarHeight();
                break;
            case MotionEvent.ACTION_MOVE:
                xInScreen = event.getRawX();
                yInScreen = event.getRawY() - getStatusBarHeight();
                // 手指移动的时候更新小悬浮窗的位置
                updateViewPosition();
                break;
            case MotionEvent.ACTION_UP:
                // 如果手指离开屏幕时，xDownInScreen和xInScreen相等，且yDownInScreen和yInScreen相等，则视为触发了单击事件。
                if (xDownInScreen == xInScreen && yDownInScreen == yInScreen) {
                    // 点击做些事

                } else {

                }
                break;
            default:
                break;
        }
        return true;
    }

    /**
     * 将小悬浮窗的参数传入，用于更新小悬浮窗的位置。
     *
     * @param params 小悬浮窗的参数
     */
    public void setParams(WindowManager.LayoutParams params) {
        mParams = params;
    }

    /**
     * 更新小悬浮窗在屏幕中的位置。
     */
    private void updateViewPosition() {
        mParams.x = (int) (xInScreen - xInView);
        mParams.y = (int) (yInScreen - yInView);
        windowManager.updateViewLayout(this, mParams);
    }

    private int getNowStatusBarHeight() {
        int[] screenParams = new int[2];
        this.getLocationOnScreen(screenParams);
        // 如果状态栏隐藏，返回0，如果状态栏显示则返回高度
        return screenParams[1];
    }

    /**
     * 用于获取状态栏的高度。
     *
     * @return 返回状态栏高度的像素值。
     */
    private int getStatusBarHeight() {
        if (MyWindowManager.getStatusBarHeight()) {
            return 0;
        }
        if (statusBarHeight == 0) {
            try {
                Class<?> c = Class.forName("com.android.internal.R$dimen");
                Object o = c.newInstance();
                Field field = c.getField("status_bar_height");
                int x = (Integer) field.get(o);
                statusBarHeight = getResources().getDimensionPixelSize(x);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return statusBarHeight;
    }

    private void addVoice(String name) {
        mVoiceList.clear();

        String voicePath = LocalPath.VOICE_PATH + name + "/";
        List<String> voiceList = FilesUtil.getVoiceFileName(voicePath);
        int id = 0;
        for (String voice : voiceList) {
            id++;
            mVoiceList.add(new WinVoiceItem(id + "", id + "", voice, voicePath + voice, getContext().getString(R.string.no_label)));
        }

        mVoiceLabelList.clear();
        mVoiceLabelList.add(new WinVoiceLabelItem("0", getContext().getString(R.string.whole)));
        List<String> labelList = FilesUtil.getFolderName(voicePath);
        for (String label : labelList) {
            String voiceLabelPath = voicePath + label + "/";
            List<String> voiceLabelList = FilesUtil.getVoiceFileName(voiceLabelPath);
            if (voiceLabelList.size() > 0) {
                for (String voice : voiceLabelList) {
                    id++;
                    mVoiceList.add(new WinVoiceItem(id + "", id + "", voice, voiceLabelPath + voice, label));
                }
                mVoiceLabelList.add(new WinVoiceLabelItem("0", label));
            } else {
                // 标签下没东西就删了
                FilesUtil.delete(voiceLabelPath);
            }
        }
        mVoiceLabelAdapter.notifyDataSetChanged();

        mVoiceAdapter.notifyDataSetChanged();

        mAllVoiceList.clear();
        mAllVoiceList.addAll(mVoiceList);
    }

    private void addQQVoice() {
        mVoiceList.clear();

        mVoiceLabelList.clear();
        mVoiceLabelList.add(new WinVoiceLabelItem("0", getContext().getString(R.string.whole)));
        String voicePath = LocalPath.QQ_VOICE_PATH;
        List<String> labelList = FilesUtil.getFolderName(voicePath);
        int id = 0;
        for (String label : labelList) {
            String voiceLabelPath = voicePath + label + qqReceiveVoicePath;
            if (!RegexUtil.isQQNumber(label) || !FilesUtil.isFileExists(voiceLabelPath)) {
                continue;
            }
            List<String> voiceList = FilesUtil.getVoiceFileName(voiceLabelPath);
            if (voiceList.size() > 0) {
                for (String voice : voiceList) {
                    id++;
                    String voiceName = voice.substring(voice.length() - 18, voice.length());
                    mVoiceList.add(new WinVoiceItem(id + "", id + "", voiceName, voiceLabelPath + voice, label, FilesUtil.getFileTime(voiceLabelPath + voice)));
                }
                mVoiceLabelList.add(new WinVoiceLabelItem("0", label));
            }
        }
        Collections.sort(mVoiceList);  // 对象数组排序
        while (mVoiceList.size() > LocalPath.VOICE_NUM) {
            FilesUtil.delete(mVoiceList.get(LocalPath.VOICE_NUM).getVoice());
            mVoiceList.remove(LocalPath.VOICE_NUM);
        }

        mVoiceLabelAdapter.notifyDataSetChanged();
        mVoiceAdapter.notifyDataSetChanged();

        mAllVoiceList.clear();
        mAllVoiceList.addAll(mVoiceList);
    }

    private void addWXVoice() {
        mVoiceList.clear();

        mVoiceLabelList.clear();
        mVoiceLabelList.add(new WinVoiceLabelItem("0", getContext().getString(R.string.whole)));
        String voicePath = LocalPath.WX_VOICE_PATH;
        List<String> labelList = FilesUtil.getFolderName(voicePath);
        int id = 0;
        for (String label : labelList) {
            String voiceLabelPath = voicePath + label + "/" + "voice2/";
            if (label.length() < 25 || !FilesUtil.isFileExists(voiceLabelPath)) {
                continue;
            }
            List<String> voicePathList = FilesUtil.getAllVoiceFileName(voiceLabelPath);
            if (voicePathList.size() > 0) {
                for (String path : voicePathList) {
                    id++;
                    String voiceName = FilesUtil.getFileNameHandExtension(path);
                    voiceName = voiceName.substring(voiceName.length() - 18, voiceName.length());
                    mVoiceList.add(new WinVoiceItem(id + "", id + "", voiceName, path, label, FilesUtil.getFileTime(path)));
                }
                mVoiceLabelList.add(new WinVoiceLabelItem("0", label));
            }
        }
        Collections.sort(mVoiceList);  // 对象数组排序
        while (mVoiceList.size() > LocalPath.VOICE_NUM) {
            FilesUtil.delete(mVoiceList.get(LocalPath.VOICE_NUM).getVoice());
            mVoiceList.remove(LocalPath.VOICE_NUM);
        }

        mVoiceLabelAdapter.notifyDataSetChanged();
        mVoiceAdapter.notifyDataSetChanged();

        mAllVoiceList.clear();
        mAllVoiceList.addAll(mVoiceList);
    }

    private void addVoicePackage() {
        mVoicePackageList.clear();

        voicePackageId = 0;
        addPackage();

        mVoicePackageAdapter.notifyDataSetChanged(); // 刷新数据
    }

    private void addPackage() {
        mVoicePackageList.add(new WinVoicePackageItem(voicePackageId + "", voicePackageId + "", "QQ收发的所有语音"));
        mVoicePackageList.add(new WinVoicePackageItem(voicePackageId + "", voicePackageId + "", "微信收发的所有语音"));

        String voicePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/moxing/voice/";
        List<String> voicePackageList = FilesUtil.getFolderName(voicePath);
        for (String voicePackage : voicePackageList) {
            voicePackageId++;
            mVoicePackageList.add(new WinVoicePackageItem(voicePackageId + "", voicePackageId + "", voicePackage));
        }
    }

    private void initMediaPlayer() {
        mp = new MediaPlayer();
        mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer arg0) {
                // TODO Auto-generated method stub
                play = false;
            }
        });
    }

    private void playVoiceType(final int position) {
        switch (MyWindowManager.getStartType()) {
            case MyWindowManager.GAME:
                playVoice(position);
                break;
            case MyWindowManager.QQ:
                replaceQQVoice(position);
                break;
            case MyWindowManager.WX:
                replaceWXVoice(position);
                break;
        }
    }

    private void replaceWXVoice(final int position) {
        String fileName[] = FilesUtil.getFileName(mVoiceList.get(position).getName());
        if (!fileName[1].equals("slk") && !fileName[1].equals("amr")) {
            uiShowToast("现微信只支持替换slk或amr文件");
            return;
        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                // 记录当前时间
                long replaceAfterTime = System.currentTimeMillis(); // 获取系统时间的10位的时间戳
                boolean replace = false;

                uiShowToast("请点击微信中的按住说话");

                while (!replace) {
                    List<WinVoiceItem> wxVoiceList = new ArrayList<>();
                    String voicePath = LocalPath.WX_VOICE_PATH;
                    List<String> labelList = FilesUtil.getFolderName(voicePath);
                    int id = 0;
                    for (String label : labelList) {
                        String voiceLabelPath = voicePath + label + "/" + "voice2/";
                        if (label.length() < 25 || !FilesUtil.isFileExists(voiceLabelPath)) {
                            continue;
                        }
                        List<String> voicePathList = FilesUtil.getAllVoiceFileName(voiceLabelPath);
                        if (voicePathList.size() > 0) {
                            for (String path : voicePathList) {
                                id++;
                                String voiceName = FilesUtil.getFileNameHandExtension(path);
                                voiceName = voiceName.substring(voiceName.length() - 18, voiceName.length());
                                wxVoiceList.add(new WinVoiceItem(id + "", id + "", voiceName, path, label));
                            }
                        }
                    }
                    for (WinVoiceItem item : wxVoiceList) {
                        Long voiceTime = FilesUtil.getFileTime(item.getVoice());
                        if (voiceTime > replaceAfterTime) {
                            String oldPath = mVoiceList.get(position).getVoice();
                            String newPath = item.getVoice();
                            FilesUtil.delete(item.getVoice());
                            FilesUtil.copyFile(oldPath, newPath);

                            uiShowToast("替换成功，可以发送。");
                            replace = true;
                            break;
                        }
                    }
                    if (System.currentTimeMillis() > replaceAfterTime + 10 * 1000) {
                        for (String label : labelList) {
                            String voiceLabelPath = voicePath + label + "/" + "voice2/";
                            if (label.length() < 25 || !FilesUtil.isFileExists(voiceLabelPath)) {
                                continue;
                            }
                            FilesUtil.delete(voiceLabelPath);
                        }
                        uiShowToast("替换失败，请重新尝试。");
                        replace = true;
                    }
                }
            }
        }).start();
    }

    private void replaceQQVoice(int position) {
        List<String> qqList = new ArrayList<String>();
        List<WinVoiceItem> qqVoiceList = new ArrayList<WinVoiceItem>();

        String voicePath = LocalPath.QQ_VOICE_PATH;
        List<String> labelList = FilesUtil.getFolderName(voicePath);
        int id = 0;
        for (String label : labelList) {
            String voiceLabelPath = voicePath + label + qqSendVoicePath;
            if (!RegexUtil.isQQNumber(label) || !FilesUtil.isFileExists(voiceLabelPath)) {
                continue;
            }
            qqList.add(label);
            List<String> voiceLabelList = FilesUtil.getVoiceFileName(voiceLabelPath);
            if (voiceLabelList.size() > 0) {
                for (String voice : voiceLabelList) {
                    id++;
                    qqVoiceList.add(new WinVoiceItem(id + "", id + "", voice, voiceLabelPath + voice, label, FilesUtil.getFileTime(voiceLabelPath + voice)));
                }
            }
        }

        if (qqVoiceList.size() == 0) {
            ToastUtil.showShort(getContext(), "请先录音，录音结束后点击替换。");
            return;
        }

        long newTime = 0;
        WinVoiceItem newVoiceItem = qqVoiceList.get(qqVoiceList.size() - 1);
        for (WinVoiceItem item : qqVoiceList) {
            if (item.getTime() > newTime) {
                newVoiceItem = item;
                newTime = item.getTime();
            }
        }

        String oldPath = mVoiceList.get(position).getVoice();
        String newPath = newVoiceItem.getVoice();
        if (oldPath.equals(newPath)) {
            ToastUtil.showShort(getContext(), "两次的语音文件一样，不可替换。");
            return;
        }
        FilesUtil.delete(newPath);
        FilesUtil.copyFile(oldPath, newPath);
        ToastUtil.showShort(getContext(), "确保是停止录音之后替换的，如果是则替换成功,可以发送。");
    }

    private void playVoice(int position) {
        if (mp != null && mp.isPlaying() && playTag == position) {
            mp.stop();
            play = false;
        } else {
            try {
                if (mp != null) {
                    mp.reset();
                }
                Uri uri = Uri.parse(mVoiceList.get(position).getVoice());
                mp = MediaPlayer.create(getContext(), uri);//重新设置要播放的音频
                mp.start();//开始播放
                play = true;
            } catch (Exception e) {
                e.printStackTrace();//输出异常信息
            }
        }
        playTag = position;
    }

    private void uiShowToast(final String msg) {
        tvTitle.post(new Runnable() {
            @Override
            public void run() {
                ToastUtil.showShort(getContext(), msg);
            }
        });
    }

    @Override
    protected void onDetachedFromWindow() {
//        if (mp.isPlaying()) {
//            mp.stop();
//        }
//        mp.release();//释放资源
        super.onDetachedFromWindow();
    }
}
